package cn.lanqiao.springboot.interceptor;

import cn.lanqiao.springboot.util.CurrentUserUtil;
import cn.lanqiao.springboot.util.Result;
import cn.lanqiao.springboot.vo.UserVO;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.regex.Pattern;

@Component
public class RedisLoginInterceptor implements HandlerInterceptor {

    /**
     * 在yaml配置文件中读取秘钥
     */
//    @Value("${cn.lanqiao.key}")
//    private String key;

    @Autowired
    RedisTemplate<String,Object> redisTemplate;
    /**
     * 使用拦截器实现JWT登录验证
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            //获得token操作
            String token = request.getHeader("Authorization");
            if (token == null) {
                return failResult(405, "请先登录！！", response);
            }
            //解密操作
            //后续操作
            UserVO user = (UserVO)redisTemplate.opsForHash().get("user_token",token.substring(7));
            if(user == null){
                return failResult(406, "登录已失效，请重新登录！！", response);
            }
            CurrentUserUtil.set(user);
            System.out.println(user);

            //鉴权
            String url = request.getRequestURI();//  url = /user/list
            //在数据库Auth获得list<Auth>   /user/*  /role/*  /menu/*
            String auths[] = {"^\\/user\\/.*","^\\/menu\\/.*"};    //redis.get(roleId)
            for (String auth : auths) {
                if(Pattern.matches(auth, url)){
                    return true;
                }
            }
            return failResult(408, "权限不足！", response);
        } catch (JWTDecodeException e) {
            return failResult(406, "秘钥格式错误！", response);
        } catch (SignatureVerificationException e) {
            return failResult(407, "秘钥解密错误！", response);
        } catch (TokenExpiredException e) {
            return failResult(408, "token过期，请重新登录！", response);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 验证失败统一向前端返回错误结果
     *
     * @param code     错误码
     * @param message  错误信息
     * @param response 响应对象
     */
    public boolean failResult(int code, String message, HttpServletResponse response) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();//使用jackson，也可以使用fastjson
            response.setStatus(code);
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding("UTF-8");
            response.getWriter().print(objectMapper.writeValueAsString(Result.error(code, message)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
